package com.zhou.util;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;

@Slf4j
public class FileUtil {
    public static final String[] PHOTO_PREFIX = new String[]{"JPEG","JPG","GIF","BMP","PNG"};
    private static final String[] VIDEO_PREFIX = new String[]{"MP4","3GP","AVI"};
    private static final String[] MUSIC_PREFIX = new String[]{"MP3","KGMA","WAV"};
    /**
     * 去掉结尾斜杠
     */
    public static String formatFilePath(String s){
        if(StringTool.isNotEmpty(s)){
            s = s.replace("\\","/");
            if(s.endsWith("/")){
                s = s.substring(0,s.length() -1);
            }
            return s;
        }
        return "";
    }
    public static boolean isPhoto(String s){
        for (String prefix : PHOTO_PREFIX) {
            if(s.toUpperCase().endsWith(prefix)){
                return true;
            }
        }
        return false;
    }
    public static boolean isVideo(String s){
        for (String prefix : VIDEO_PREFIX) {
            if(s.toUpperCase().endsWith(prefix)){
                return true;
            }
        }
        return false;
    }
    public static boolean isMusic(String s){
        for (String prefix : MUSIC_PREFIX) {
            if(s.toUpperCase().endsWith(prefix)){
                return true;
            }
        }
        return false;
    }
    public static boolean isWord(String s){
        s = s.toUpperCase();
        return s.endsWith("DOCX") || s.endsWith("DOC");
    }
    public static boolean isExcel(String s){
        s = s.toUpperCase();
        return s.endsWith("XLSX") || s.endsWith("XLS");
    }
    public static boolean isPpt(String s){
        s = s.toUpperCase();
        return s.endsWith("PPTX") || s.endsWith("PPT");
    }
    public static byte[] toByte(File file) throws Exception{
        FileInputStream in = null;
        try{
            in = new FileInputStream(file);
            return IOUtils.toByteArray(in);
        }finally {
            IOUtils.closeQuietly(in);
        }
    }

    public static String getPrefix(File f) {
        return getPrefix(f.getAbsolutePath());
    }
    public static String getPrefix(String f) {
        int index;
        String prefix = null;
        if(StringTool.isNotEmpty(f) && (index = f.lastIndexOf(".")) > -1 && index < f.length() -1){
            return f.substring(index + 1);
        }
        return prefix;
    }
    public static String sizeToChinese(Long size){
        StringBuilder res = new StringBuilder();
        if (size == null) {
            return "";
        }
        long s1 = 1000;
        long s2 = s1*1000;
        long s3 = s2*1000;
        if(size >= s3){
            res.append(size/s3);
            long y = size%s3;
            if(y > 0){
                res.append(".").append(String.valueOf(y), 0, 1);
            }
            res.append("G");
        }else if(size >= s2){
            res.append(size/s2);
            long y = size%s2;
            if(y > 0){
                res.append(".").append(String.valueOf(y), 0, 1);
            }
            res.append("M");
        }else if(size >= s1){
            res.append(size/s1);
            long y = size%s1;
            if(y > 0){
                res.append(".").append(String.valueOf(y), 0, 1);
            }
            res.append("K");
        }else{
            res.append(size).append("B");
        }


        return res.toString();
    }
    /**
     * 删除文件
     * @param filepath
     */
    public static void del(String filepath) {
        File f = new File(filepath);// 定义文件路径
        if (f.exists() )// 判断是否存在
        {
            if(f.isDirectory())//如果是文件夹
            {
                if (f.listFiles().length == 0){
                    f.delete();
                }
                else{
                    File[] delFile = f.listFiles();
                    int i = f.listFiles().length;
                    for (int j = 0; j < i; j++) {
                        if (delFile[j].isDirectory()) {
                            del(delFile[j].getAbsolutePath());
                        }
                        delFile[j].delete();
                    }
                    f.delete();
                }
            }
            else{
                f.delete();
            }
        }
    }
    public static void createDir(String path){
        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }
    }

    /**
     * 复制文件
     * @param sourceFile
     * @param targetFile
     * @throws IOException
     */
    public static void copyFile(File sourceFile, File targetFile) throws IOException
    {
        if(sourceFile.exists())
        {
            BufferedInputStream inBuff = null;
            BufferedOutputStream outBuff = null;
            try {
                // 新建文件输入流并对它进行缓冲
                inBuff = new BufferedInputStream(new FileInputStream(sourceFile));
                // 新建文件输出流并对它进行缓冲
                outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
                // 缓冲数组
                byte[] b = new byte[1024 * 5];
                int len;
                while ((len = inBuff.read(b)) != -1)
                {
                    outBuff.write(b, 0, len);
                }
                // 刷新此缓冲的输出流
                outBuff.flush();
            } finally {
                IOUtils.closeQuietly(inBuff);
                IOUtils.closeQuietly(outBuff);
            }
        }
    }

    /**
     * 向客户端下载文件,弹出下载框.
     */
    public static void exportFile(HttpServletResponse response, File file, boolean isDel) throws Exception{
        exportFile(response, file, file.getName(), isDel);
    }

    /**
     * 向客户端下载文件,弹出下载框.
     */
    public static void exportFile(HttpServletResponse response, File file, String outFileName, boolean isDel) throws Exception{
        InputStream in = null;
        try {
            in = new FileInputStream(file.getPath());
            exportFile(response, in, outFileName);
        }finally {
            IOUtils.closeQuietly(in);
            if(isDel){
                file.delete();
            }
        }
    }

    /**
     * 向客户端下载文件,弹出下载框.
     */
    public static void exportFile(HttpServletResponse response, InputStream in, String outFileName) throws IOException{
        String filename = URLEncoder.encode(outFileName, "UTF-8");
        OutputStream out;
        //对+号进行替换,Chrome无法转义带有%2B
        filename = filename.replaceAll("%2B","+");
        //对(号进行替换,Chrome无法转义带有%28
        filename = filename.replaceAll("%28","(");
        //对)号进行替换,Chrome无法转义带有%29
        filename = filename.replaceAll("%29",")");
        // 定义输出类型(下载)
        response.setContentType("application/force-download");
        response.setHeader("Location", filename);
        // 定义输出文件头
        response.setHeader("Content-Disposition", "attachment;filename="+filename);
        out=response.getOutputStream();
        byte[] buffer=new byte[1024];
        int i;
        while((i=in.read(buffer))!=-1){
            out.write(buffer, 0, i);
        }
        in.close();
        out.close();
    }

    public static void saveFile(byte[] bytes,File file){
        OutputStream out = null;
        try{
            out = new FileOutputStream(file);
            out.write(bytes);
            out.flush();
        }catch (Exception e){
            log.error("保存文件失败！",e);;
        }finally {
            IOUtils.closeQuietly(out);
        }
    }

    public static boolean exists(String fileName) {
        try {
            File file = new File(fileName);
            return file.exists();
        } catch (Exception ex){
            return false;
        }
    }
    public static void safeDelete(List<String> files) {
        if(files!= null && files.size() > 0){
            for (String file : files) {
                safeDelete(new File(file));
            }
        }
    }

    public static void safeDelete(File f) {
        try {
            if(f != null && f.exists()){
                deleteFileAll(f);
            }
        } catch (Exception ex){
            //
        }
    }
    public static void safeDelete(String f) {
        if(f != null && f.length() > 0)
        safeDelete(new File(f));
    }
    /**
     * 删除文件下所有文件夹和文件
     * file：文件名
     * */
    public static void deleteFileAll(File file) {
        if (file.exists()) {
            if(file.isFile()){
                file.delete();
            }else{
                for (File value : file.listFiles()) {
                    deleteFileAll(value);
                }
                file.delete();
            }


        }
    }

    @SneakyThrows
    public static String getStreamMd5(InputStream in){
        byte[] b = IOUtils.toByteArray(in);
        return Md5Util.hex(b);
    }

    @SneakyThrows
    public static String getFileMd5(File file){
        InputStream in = null;
        try {
            in = new FileInputStream(file);
            return getStreamMd5(in);
        } finally {
            IOUtils.closeQuietly(in);
        }
    }

}
